/// <reference path="../utilities/FXDom.js" />
/// <reference path="../utilities/Markup.js" />
/// <reference path="../utilities/Xpcom.js" />
///--------------------------------------------------------------------
/// <file name="TextAreaController.js">
///   Extends various text areas on the web site with hotkeys and
///   copy/paste fix-ups for video URLs.
/// </file>
///--------------------------------------------------------------------

NAMFox.ns(function() { with (NAMFox) {

this.TextAreaController = function(htmlDocument) {
    /// <summary>
    ///   Initializes a new instance of the TextAreaController class,
    ///   targeted toward the specified document.
    /// </summary>
    /// <param name="htmlDocument" type="Document">
    ///   The document this AutoComplete will be added to.
    /// </param>
    
    this._htmlDocument = htmlDocument;
}

TextAreaController.prototype = {
    _onKeyPress: function(event) {
        /// <summary>
        ///   Handles the keypress event of a text area. Used to
        ///   add hotkeys for special markup tags.
        /// </summary>
        /// <param name="event" type="KeyboardEvent">
        ///   Contains the event data.
        /// </param>
        
        var textArea = event.target;
        
        if (event.ctrlKey) {
            var text = {
                open: "",
                close: ""
            };
            
            $.verbose("TEXT CONTROLLER | Char Code: " + event.charCode);
            
            switch (event.charCode) {
                case 43:
                    text.open = "[sup]";
                    text.close = "[/sup]";
                    break;
                case 61:
                    text.open = "[sub]";
                    text.close = "[/sub]";
                    break;
                case 98:
                    text.open = "[b]";
                    text.close = "[/b]";
                    break;
                case 105:
                    text.open = "[i]";
                    text.close = "[/i]";
                    break;
                case 117:
                    text.open = "[u]";
                    text.close = "[/u]";
                    break;
                default:
                    return;
            }
            
            event.preventDefault();
            var selectedText = textArea.value.substring(textArea.selectionStart, textArea.selectionEnd);
            
            Markup.addText(text, textArea);
            
            var newCaretIndex = textArea.selectionStart - text.close.length;
            
            textArea.setSelectionRange(
                newCaretIndex,
                newCaretIndex
            );
        }
    },
    
    _onPaste: function(event) {
        /// <summary>
        ///   Handles the paste event of a text area. Used to
        ///   conform video URLs to the standard required by Neoseeker.
        /// </summary>
        /// <param name="event">
        ///   Contains the event data.
        /// </param>
        
        var textArea = event.target;
        var clipboard = $("@mozilla.org/widget/clipboard;1").service("nsIClipboard");
        var clipboardHelper = $("@mozilla.org/widget/clipboardhelper;1").service("nsIClipboardHelper");
        var transferable = $("@mozilla.org/widget/transferable;1").instance("nsITransferable");
        transferable.addDataFlavor("text/unicode");
        
        // Get the current data on the clipboard (before the paste occurs).
        var data = {};
        var dataLength = {};
        clipboard.getData(transferable, clipboard.kGlobalClipboard);
        transferable.getTransferData("text/unicode", data, dataLength);
        
        // Divide by 2 since there are two bytes per character.
        var pasteText = data.value.QueryInterface($("nsISupportsString"));
        pasteText = pasteText.data.substring(0, dataLength.value / 2);
        
        var previous = textArea.value.substring(0, textArea.selectionStart);
        var following = textArea.value.substring(textArea.selectionEnd);
        
        // Try finding a transformer
        for (var i = 0; i < TextAreaController.textTransformers.length; ++i) {
            var transformer = TextAreaController.textTransformers[i];
            
            if (
                transformer.previous.test(previous) &&
                transformer.following.test(following)
            ) {
                // Overwrite the pasted text with the new text.
                clipboardHelper.copyString(transformer.transform(pasteText));
                
                break;
            }
        }
    },
    
    attach: function() {
        /// <summary>
        ///   Attaches the TextAreaController to all text areas on the page.
        /// </summary>
        
        var textAreas = $FX("textarea", this._htmlDocument);
        
        for (var i = 0; i < textAreas.length; ++i) {
            this.attachSingle(textAreas.get(i));
        }
    },
    
    attachSingle: function(textArea) {
        /// <summary>
        ///   Attaches the TextAreaController to a single text area.
        ///   Useful when the text area is created dynamically.
        /// </summary>
        /// <param name="textArea" type="TextArea">
        ///   The text area to which to attach AutoComplete.
        /// </param>
        
        if (!textArea || textArea.length === 0) {
            return;
        }
        
        if (textArea.get) {
            textArea = textArea.get(0);
        }
        
        textArea.addEventListener("keypress", $.createCallback(this._onKeyPress, this), false);
        textArea.addEventListener("paste", $.createCallback(this._onPaste, this), false);
    }
};

TextAreaController.textTransformers = [
    {
        previous: /\[gamespot\]$/i,
        following: /^\[\/gamespot\]/i,
        transform: $.transformers.gamespot
    },
    {
        previous: /\[gametrailers\]$/i,
        following: /^\[\/gametrailers\]/i,
        transform: $.transformers.gametrailers
    },
    {
        previous: /\[gametrailers_uservideo\]$/i,
        following: /^\[\/gametrailers_uservideo\]/i,
        transform: $.transformers.gametrailersUser
    },
    {
        previous: /\[gamevideos\]$/i,
        following: /^\[\/gamevideos\]/i,
        transform: $.transformers.gamevideos
    }
];

}});